// Net.cpp

#include "stdafx.h"
#include "TrainNet.h"

TrainNet::TrainNet(string XMLFileURL)
{
	std::set<Line*,LinePointerComparator>::iterator			itLine;
	std::set<Station*,StationPointerComparator>::iterator	itStation;
	string			LineName;
	string			StationName;
	string			Time;
	Line*			pLine=0;
	Station*		pStation=0;
	Line*			pNewLine=0;
	Station*		pNewStation=0;
	State*			NewState=0;
	State*			OldState=0;
	TiXmlNode*		Net=0;
	TiXmlElement*	LineElement=0;
	TiXmlElement*	StationElement=0;

	TiXmlDocument Doc("Net.xml");
	Doc.LoadFile();

	// Get "net"-node-handle
	Net=Doc.FirstChild("net");
	if(Net==0)
		return;

	pNewLine=new Line();
	pNewStation=new Station();

	// go through all lines
	for(LineElement = Net->FirstChildElement();LineElement!=0;LineElement=LineElement->NextSiblingElement())
	{
		OldState=0;
		pNewLine->m_Name=LineElement->Attribute("name");
		if((itLine=Lines.find(pNewLine))!=Lines.end())
			pLine=(Line*)(*itLine);
		else
		{
			Lines.insert(pNewLine);
			pLine=pNewLine;
			pNewLine = new Line();
		}

		// go through all stations
		for(StationElement = LineElement->FirstChildElement();StationElement!=0;StationElement=StationElement->NextSiblingElement())
		{
			pNewStation->m_Name=StationElement->GetText();
			if((itStation=Stations.find(pNewStation))!=Stations.end())
				pStation=(Station*)(*itStation);
			else
			{
				Stations.insert(pNewStation);
				pStation=pNewStation;
				pNewStation = new Station();
			}
			NewState = new State(pLine, pStation);

			// add statetransition, if this is not the first station of the line
			if(OldState!=0)
				StateTransitions.push_back(new StateTransition(OldState,NewState,atoi(Time.c_str())));

			// add statetransitions, for every station shared with another line
			for(auto it = States.begin(); it!=States.end(); it++)
				if(NewState->m_Station==(*it)->m_Station)
					StateTransitions.push_back(new StateTransition((*it),NewState));

			States.push_back(NewState);
			Time=StationElement->Attribute("time");
			OldState=NewState;
		}
	}

	delete pNewStation;
	delete pNewLine;
}
//-------------------------------
TrainNet::~TrainNet()
{
	State* St;
	StateTransition* StTr;

	for(unsigned int i=0;i<States.size();i++)
	{
		St=States.back();
		States.pop_back();
		delete St;
	}
	for(unsigned int i=0;i<StateTransitions.size();i++)
	{
		StTr=StateTransitions.back();
		StateTransitions.pop_back();
		delete StTr;
	}
	for(auto itSt=Stations.begin();itSt!=Stations.end();itSt++)
	{
		delete (Station*)(*itSt);
		(Station*)(*itSt)=0;
	}
	for(auto itLi=Lines.begin();itLi!=Lines.end();itLi++)
	{
		delete (Line*)(*itLi);
		(Line*)(*itLi)=0;
	}
}
//-------------------------------
bool TrainNet::DoesStationExist(string StationName)
{
	Station stat;
	stat.m_Name=StationName;
	return Stations.find(&stat)!=Stations.end();
}
//-------------------------------
Station* TrainNet::FindStationByName(string StationName)
{
	for(auto it = States.begin(); it!=States.end(); it++)
		if(StationName==(*it)->m_Station->m_Name)
			return (*it)->m_Station;
	return false;
}
//-------------------------------
State* TrainNet::FindAnyStateForStation(Station* Station)
{
	for(auto it = States.begin(); it!=States.end(); it++)
		if(Station==(*it)->m_Station)
			return (*it);
	return 0;
}